package com.lifeverse.service;

import com.lifeverse.entity.DigitalDNA;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.exception.BusinessException;
import com.lifeverse.repository.DigitalDNARepository;
import com.lifeverse.repository.LifeEntityRepository;
import com.lifeverse.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 数字DNA服务类
 * 提供DNA的基础管理功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class DigitalDNAService {
    
    private final DigitalDNARepository digitalDNARepository;
    private final LifeEntityRepository lifeEntityRepository;
    private final GeneExpressionEngine geneExpressionEngine;
    private final FeatureMapper featureMapper;
    
    /**
     * 创建新的数字DNA
     */
    @Transactional
    public DigitalDNA createDNA(Long lifeEntityId, Map<String, Object> geneData) {
        log.info("Creating DNA for life entity: {}", lifeEntityId);
        
        // 验证生命体是否存在
        LifeEntity lifeEntity = lifeEntityRepository.findByIdAndDeletedFalse(lifeEntityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + lifeEntityId));
        
        // 检查是否已存在DNA
        Optional<DigitalDNA> existingDNA = digitalDNARepository.findByLifeEntityIdAndDeletedFalse(lifeEntityId);
        if (existingDNA.isPresent()) {
            throw new BusinessException("生命体已存在DNA: " + lifeEntityId);
        }
        
        // 创建DNA实例
        DigitalDNA dna = new DigitalDNA();
        dna.setLifeEntity(lifeEntity);
        dna.setGeneSequence(JsonUtils.toJson(geneData));
        
        // 使用特征映射器设置基因强度
        featureMapper.mapFeaturesToDNA(dna, geneData);
        
        // 计算特征哈希
        String featureHash = featureMapper.calculateFeatureHash(dna);
        dna.setFeatureHash(featureHash);
        
        // 设置初始值
        dna.setDnaVersion(1);
        dna.setGeneration(1);
        dna.setFitnessScore(BigDecimal.valueOf(50.0));
        dna.setMutationRate(BigDecimal.valueOf(0.001));
        dna.setStabilityScore(BigDecimal.valueOf(100.0));
        dna.setExpressionActivity(BigDecimal.valueOf(50.0));
        
        DigitalDNA savedDNA = digitalDNARepository.save(dna);
        log.info("Created DNA with ID: {} for life entity: {}", savedDNA.getId(), lifeEntityId);
        
        return savedDNA;
    }
    
    /**
     * 根据ID查询DNA
     */
    public Optional<DigitalDNA> findById(Long id) {
        return digitalDNARepository.findById(id)
                .filter(dna -> !dna.getDeleted());
    }
    
    /**
     * 根据生命体ID查询DNA
     */
    public Optional<DigitalDNA> findByLifeEntityId(Long lifeEntityId) {
        return digitalDNARepository.findByLifeEntityIdAndDeletedFalse(lifeEntityId);
    }
    
    /**
     * 根据特征哈希查询DNA
     */
    public Optional<DigitalDNA> findByFeatureHash(String featureHash) {
        return digitalDNARepository.findByFeatureHashAndDeletedFalse(featureHash);
    }
    
    /**
     * 分页查询高适应度DNA
     */
    public Page<DigitalDNA> findHighFitnessDNA(BigDecimal minFitness, Pageable pageable) {
        return digitalDNARepository.findHighFitnessDNA(minFitness, pageable);
    }
    
    /**
     * 查询稳定的DNA
     */
    public List<DigitalDNA> findStableDNA(BigDecimal minStability) {
        return digitalDNARepository.findStableDNA(minStability);
    }
    
    /**
     * 查询活跃的DNA
     */
    public List<DigitalDNA> findActiveDNA(BigDecimal minActivity) {
        return digitalDNARepository.findActiveDNA(minActivity);
    }
    
    /**
     * 更新DNA
     */
    @Transactional
    public DigitalDNA updateDNA(Long id, Map<String, Object> updateData) {
        log.info("Updating DNA: {}", id);
        
        DigitalDNA dna = digitalDNARepository.findById(id)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("DNA不存在: " + id));
        
        // 更新基因序列
        if (updateData.containsKey("geneSequence")) {
            dna.setGeneSequence(JsonUtils.toJson(updateData.get("geneSequence")));
        }
        
        // 更新基因强度
        featureMapper.mapFeaturesToDNA(dna, updateData);
        
        // 重新计算特征哈希
        String newFeatureHash = featureMapper.calculateFeatureHash(dna);
        dna.setFeatureHash(newFeatureHash);
        
        // 更新版本号
        dna.setDnaVersion(dna.getDnaVersion() + 1);
        
        DigitalDNA savedDNA = digitalDNARepository.save(dna);
        log.info("Updated DNA: {}", id);
        
        return savedDNA;
    }
    
    /**
     * 表达DNA基因
     */
    @Transactional
    public Map<String, Object> expressGenes(Long dnaId, Map<String, Object> environment) {
        log.info("Expressing genes for DNA: {}", dnaId);
        
        DigitalDNA dna = digitalDNARepository.findById(dnaId)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("DNA不存在: " + dnaId));
        
        // 使用基因表达引擎进行表达
        Map<String, Object> expressionResult = geneExpressionEngine.expressGenes(dna, environment);
        
        // 更新表达时间和活跃度
        dna.updateLastExpressionTime();
        dna.setExpressionActivity(calculateExpressionActivity(expressionResult));
        
        digitalDNARepository.save(dna);
        
        log.info("Gene expression completed for DNA: {}", dnaId);
        return expressionResult;
    }
    
    /**
     * DNA变异
     */
    @Transactional
    public DigitalDNA mutateDNA(Long dnaId, BigDecimal mutationIntensity) {
        log.info("Mutating DNA: {} with intensity: {}", dnaId, mutationIntensity);
        
        DigitalDNA dna = digitalDNARepository.findById(dnaId)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("DNA不存在: " + dnaId));
        
        // 执行变异
        DigitalDNA mutatedDNA = performMutation(dna, mutationIntensity);
        
        // 更新变异时间
        mutatedDNA.updateLastMutationTime();
        mutatedDNA.setDnaVersion(mutatedDNA.getDnaVersion() + 1);
        
        // 重新计算特征哈希
        String newFeatureHash = featureMapper.calculateFeatureHash(mutatedDNA);
        mutatedDNA.setFeatureHash(newFeatureHash);
        
        DigitalDNA savedDNA = digitalDNARepository.save(mutatedDNA);
        log.info("DNA mutation completed: {}", dnaId);
        
        return savedDNA;
    }
    
    /**
     * DNA交叉繁殖
     */
    @Transactional
    public DigitalDNA crossoverDNA(Long parentDnaId, Long motherDnaId, Long offspringLifeEntityId) {
        log.info("Crossover DNA: parent={}, mother={}, offspring={}", parentDnaId, motherDnaId, offspringLifeEntityId);
        
        DigitalDNA parentDNA = digitalDNARepository.findById(parentDnaId)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("父DNA不存在: " + parentDnaId));
        
        DigitalDNA motherDNA = digitalDNARepository.findById(motherDnaId)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("母DNA不存在: " + motherDnaId));
        
        LifeEntity offspringEntity = lifeEntityRepository.findByIdAndDeletedFalse(offspringLifeEntityId)
                .orElseThrow(() -> new BusinessException("后代生命体不存在: " + offspringLifeEntityId));
        
        // 执行交叉繁殖
        DigitalDNA offspringDNA = performCrossover(parentDNA, motherDNA, offspringEntity);
        
        DigitalDNA savedDNA = digitalDNARepository.save(offspringDNA);
        log.info("DNA crossover completed, offspring DNA ID: {}", savedDNA.getId());
        
        return savedDNA;
    }
    
    /**
     * 计算DNA相似度
     */
    public BigDecimal calculateSimilarity(Long dnaId1, Long dnaId2) {
        DigitalDNA dna1 = digitalDNARepository.findById(dnaId1)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("DNA不存在: " + dnaId1));
        
        DigitalDNA dna2 = digitalDNARepository.findById(dnaId2)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("DNA不存在: " + dnaId2));
        
        return dna1.calculateSimilarity(dna2);
    }
    
    /**
     * 删除DNA
     */
    @Transactional
    public void deleteDNA(Long id) {
        log.info("Deleting DNA: {}", id);
        
        DigitalDNA dna = digitalDNARepository.findById(id)
                .filter(d -> !d.getDeleted())
                .orElseThrow(() -> new BusinessException("DNA不存在: " + id));
        
        dna.setDeleted(true);
        digitalDNARepository.save(dna);
        
        log.info("DNA deleted: {}", id);
    }
    
    /**
     * 获取DNA统计信息
     */
    public Map<String, Object> getDNAStatistics() {
        return Map.of(
                "averageFitnessScore", digitalDNARepository.getAverageFitnessScore(),
                "averageStabilityScore", digitalDNARepository.getAverageStabilityScore(),
                "averageExpressionActivity", digitalDNARepository.getAverageExpressionActivity(),
                "maxGeneration", digitalDNARepository.getMaxGeneration(),
                "generationCounts", digitalDNARepository.countByGeneration()
        );
    }
    
    /**
     * 执行DNA变异的私有方法
     */
    private DigitalDNA performMutation(DigitalDNA originalDNA, BigDecimal mutationIntensity) {
        // 创建变异后的DNA副本
        DigitalDNA mutatedDNA = new DigitalDNA();
        mutatedDNA.setLifeEntity(originalDNA.getLifeEntity());
        mutatedDNA.setGeneSequence(originalDNA.getGeneSequence());
        mutatedDNA.setGeneration(originalDNA.getGeneration());
        mutatedDNA.setParentDnaId(originalDNA.getId());
        
        // 应用变异到各个基因强度
        BigDecimal mutationFactor = mutationIntensity.multiply(BigDecimal.valueOf(0.1)); // 10%的变异范围
        
        mutatedDNA.setLearningGeneStrength(applyMutation(originalDNA.getLearningGeneStrength(), mutationFactor));
        mutatedDNA.setCreativityGeneStrength(applyMutation(originalDNA.getCreativityGeneStrength(), mutationFactor));
        mutatedDNA.setCollaborationGeneStrength(applyMutation(originalDNA.getCollaborationGeneStrength(), mutationFactor));
        mutatedDNA.setAdaptabilityGeneStrength(applyMutation(originalDNA.getAdaptabilityGeneStrength(), mutationFactor));
        mutatedDNA.setEmotionGeneStrength(applyMutation(originalDNA.getEmotionGeneStrength(), mutationFactor));
        mutatedDNA.setLogicGeneStrength(applyMutation(originalDNA.getLogicGeneStrength(), mutationFactor));
        mutatedDNA.setIntuitionGeneStrength(applyMutation(originalDNA.getIntuitionGeneStrength(), mutationFactor));
        mutatedDNA.setSocialGeneStrength(applyMutation(originalDNA.getSocialGeneStrength(), mutationFactor));
        
        // 更新变异率和稳定性
        mutatedDNA.setMutationRate(originalDNA.getMutationRate().multiply(BigDecimal.valueOf(1.1))); // 变异率略微增加
        mutatedDNA.setStabilityScore(originalDNA.getStabilityScore().multiply(BigDecimal.valueOf(0.95))); // 稳定性略微降低
        mutatedDNA.setFitnessScore(originalDNA.getFitnessScore()); // 适应度需要重新评估
        mutatedDNA.setExpressionActivity(originalDNA.getExpressionActivity());
        
        return mutatedDNA;
    }
    
    /**
     * 执行DNA交叉繁殖的私有方法
     */
    private DigitalDNA performCrossover(DigitalDNA parentDNA, DigitalDNA motherDNA, LifeEntity offspringEntity) {
        DigitalDNA offspringDNA = new DigitalDNA();
        offspringDNA.setLifeEntity(offspringEntity);
        offspringDNA.setParentDnaId(parentDNA.getId());
        offspringDNA.setMotherDnaId(motherDNA.getId());
        offspringDNA.setGeneration(Math.max(parentDNA.getGeneration(), motherDNA.getGeneration()) + 1);
        
        // 基因交叉：随机选择父母的基因
        offspringDNA.setLearningGeneStrength(Math.random() > 0.5 ? parentDNA.getLearningGeneStrength() : motherDNA.getLearningGeneStrength());
        offspringDNA.setCreativityGeneStrength(Math.random() > 0.5 ? parentDNA.getCreativityGeneStrength() : motherDNA.getCreativityGeneStrength());
        offspringDNA.setCollaborationGeneStrength(Math.random() > 0.5 ? parentDNA.getCollaborationGeneStrength() : motherDNA.getCollaborationGeneStrength());
        offspringDNA.setAdaptabilityGeneStrength(Math.random() > 0.5 ? parentDNA.getAdaptabilityGeneStrength() : motherDNA.getAdaptabilityGeneStrength());
        offspringDNA.setEmotionGeneStrength(Math.random() > 0.5 ? parentDNA.getEmotionGeneStrength() : motherDNA.getEmotionGeneStrength());
        offspringDNA.setLogicGeneStrength(Math.random() > 0.5 ? parentDNA.getLogicGeneStrength() : motherDNA.getLogicGeneStrength());
        offspringDNA.setIntuitionGeneStrength(Math.random() > 0.5 ? parentDNA.getIntuitionGeneStrength() : motherDNA.getIntuitionGeneStrength());
        offspringDNA.setSocialGeneStrength(Math.random() > 0.5 ? parentDNA.getSocialGeneStrength() : motherDNA.getSocialGeneStrength());
        
        // 设置初始属性
        offspringDNA.setDnaVersion(1);
        offspringDNA.setMutationRate(parentDNA.getMutationRate().add(motherDNA.getMutationRate()).divide(BigDecimal.valueOf(2), 4, java.math.RoundingMode.HALF_UP));
        offspringDNA.setStabilityScore(BigDecimal.valueOf(100.0));
        offspringDNA.setFitnessScore(BigDecimal.valueOf(50.0));
        offspringDNA.setExpressionActivity(BigDecimal.valueOf(50.0));
        
        // 构建基因序列
        Map<String, Object> geneData = Map.of(
                "learning", offspringDNA.getLearningGeneStrength(),
                "creativity", offspringDNA.getCreativityGeneStrength(),
                "collaboration", offspringDNA.getCollaborationGeneStrength(),
                "adaptability", offspringDNA.getAdaptabilityGeneStrength(),
                "emotion", offspringDNA.getEmotionGeneStrength(),
                "logic", offspringDNA.getLogicGeneStrength(),
                "intuition", offspringDNA.getIntuitionGeneStrength(),
                "social", offspringDNA.getSocialGeneStrength()
        );
        offspringDNA.setGeneSequence(JsonUtils.toJson(geneData));
        
        return offspringDNA;
    }
    
    /**
     * 应用变异到基因强度
     */
    private BigDecimal applyMutation(BigDecimal originalValue, BigDecimal mutationFactor) {
        // 生成-1到1之间的随机数
        double randomFactor = (Math.random() - 0.5) * 2;
        BigDecimal mutation = mutationFactor.multiply(BigDecimal.valueOf(randomFactor));
        BigDecimal newValue = originalValue.add(mutation);
        
        // 确保值在0-100范围内
        if (newValue.compareTo(BigDecimal.ZERO) < 0) {
            return BigDecimal.ZERO;
        }
        if (newValue.compareTo(BigDecimal.valueOf(100)) > 0) {
            return BigDecimal.valueOf(100);
        }
        
        return newValue;
    }
    
    /**
     * 计算表达活跃度
     */
    private BigDecimal calculateExpressionActivity(Map<String, Object> expressionResult) {
        // 基于表达结果计算活跃度
        int activeGenes = 0;
        for (Object value : expressionResult.values()) {
            if (value instanceof Number && ((Number) value).doubleValue() > 0.5) {
                activeGenes++;
            }
        }
        
        return BigDecimal.valueOf((double) activeGenes / expressionResult.size() * 100);
    }
}